import logging
import threading
from typing import Dict, Any, Optional

# 导入服务类
from category import CategoryManager
from html_parser import HTMLProcessor
from embedding import EmbeddingService
from services.config_service import ConfigService

# 导入统一的日志配置模块
from log_config import setup_logging

# 导入线程池管理器
from utils.thread_pool_manager import thread_pool_manager

# 配置日志
setup_logging()
logger = logging.getLogger(__name__)


class ServiceContainer:
    """
    服务容器，用于管理应用程序中所有服务的生命周期和依赖关系
    采用单例模式实现
    """
    _instance = None
    _lock = threading.RLock()

    def __new__(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = super(ServiceContainer, cls).__new__(cls)
                # 初始化服务容器
                cls._instance._initialized = False
        return cls._instance

    def __init__(self):
        """初始化服务容器，确保只初始化一次"""
        with self._lock:
            if not self._initialized:
                self._services = {}
                self._initialized = True

    def initialize(self):
        """
        初始化所有服务
        按照依赖关系的顺序创建服务
        """
        logger.info("开始初始化服务容器")
        
        # 1. 首先初始化配置服务
        self._services['config_service'] = self._create_config_service()
        
        # 2. 初始化其他基础服务
        self._services['thread_pool'] = self._create_thread_pool()
        self._services['category_manager'] = self._create_category_manager()
        self._services['html_processor'] = self._create_html_processor()
        
        # 3. 初始化依赖其他服务的复杂服务
        self._services['embedding_service'] = self._create_embedding_service()
        
        logger.info("服务容器初始化完成")

    def _create_config_service(self) -> ConfigService:
        """创建配置服务"""
        logger.debug("创建配置服务")
        return ConfigService.get_instance()

    def _create_thread_pool(self):
        """使用线程池管理器创建和配置线程池"""
        logger.debug("通过线程池管理器初始化线程池")
        # 初始化线程池管理器
        thread_pool_manager.initialize()
        # 返回线程池实例
        return thread_pool_manager.get_thread_pool()

    def _create_category_manager(self) -> CategoryManager:
        """创建分类管理器"""
        logger.debug("创建分类管理器")
        config_service = self.get_service('config_service')
        category_config = config_service.get_category_config()
        
        return CategoryManager(
            category_dir=category_config['category_dir'],
            category_file=category_config['category_file']
        )

    def _create_html_processor(self) -> HTMLProcessor:
        """创建HTML处理器"""
        logger.debug("创建HTML处理器")
        return HTMLProcessor()

    def _create_embedding_service(self) -> EmbeddingService:
        """创建嵌入服务"""
        logger.debug("创建嵌入服务")
        
        # 获取依赖的服务
        config_service = self.get_service('config_service')
        category_manager = self.get_service('category_manager')
        html_processor = self.get_service('html_processor')
        
        # 获取配置
        embedding_config = config_service.get_embedding_config()
        rerank_config = config_service.get_rerank_config()
        backend_config = config_service.get_backend_config()
        milvus_config = config_service.get_milvus_config()
        saved_images_config = config_service.get_saved_images_config()
        
        # 提取配置值
        embedding_model_name = embedding_config['model_name']
        embedding_model_path = embedding_config['model_path']
        rerank_model_name = rerank_config['model_name']
        rerank_model_path = rerank_config['model_path']
        backend_name = backend_config['name']
        saved_images_dir = saved_images_config['saved_images_dir']
        
        logger.info(f"嵌入模型: {embedding_model_name}, {embedding_model_path}")
        logger.info(f"重排序模型: {rerank_model_name}, {rerank_model_path}")
        logger.info(f"backend_name: {backend_name}")
        logger.info(f"saved_image_dir: {saved_images_dir}")
        
        # 创建并返回嵌入服务
        try:
            return EmbeddingService(
                category_manager=category_manager,
                html_parser=html_processor,
                embedding_model_name=embedding_model_name,
                embedding_model_path=embedding_model_path,
                rerank_model_name=rerank_model_name,
                rerank_model_path=rerank_model_path,
                milvus_connection_args=milvus_config,
                backend_name=backend_name,
                saved_images_dir=saved_images_dir
            )
        except Exception as e:
            logger.error(f"初始化嵌入服务失败: {str(e)}")
            logger.error("如果您看到向量维度不匹配的错误，请使用以下命令删除不匹配的Milvus集合:")
            logger.error("  python milvus_manager.py list              - 列出所有集合")
            logger.error("  python milvus_manager.py delete <collection_name> - 删除特定集合")
            logger.error("  或使用: python milvus_manager.py delete-all  - 删除所有集合")
            logger.error("删除集合后请重新启动服务，系统将使用正确的维度创建新集合")
            raise

    def get_service(self, service_name: str) -> Any:
        """
        获取指定名称的服务实例
        
        Args:
            service_name: 服务名称
        
        Returns:
            服务实例
        
        Raises:
            KeyError: 当请求的服务不存在时
        """
        if service_name not in self._services:
            raise KeyError(f"服务 '{service_name}' 不存在")
        return self._services[service_name]

    def shutdown(self):
        """关闭所有服务，释放资源"""
        logger.info("开始关闭服务容器")
        
        # 按照依赖关系的逆序关闭服务
        if 'embedding_service' in self._services:
            try:
                self._services['embedding_service'].close()
                logger.debug("嵌入服务已关闭")
            except Exception as e:
                logger.error(f"关闭嵌入服务时出错: {str(e)}")
        
        # 使用线程池管理器关闭线程池
        try:
            thread_pool_manager.shutdown(wait=True)
            logger.debug("线程池已通过管理器关闭")
        except Exception as e:
            logger.error(f"通过管理器关闭线程池时出错: {str(e)}")
        
        # 清空服务字典
        self._services.clear()
        logger.info("服务容器已关闭")